namespace SimpleWebServices.Web.UI.Html
{
    using System;
    using System.Xml;
    using System.Xml.Serialization;
    using SimpleWebServices.Data;
    using SimpleWebServices.Web.UI.Html.Elements;
    using SimpleWebServices.Web.UI.Html.Validation;

    [XmlRoot("control")]
    public abstract class Control : Element, IControl, IXmlSerializable
    {
        protected Control()
            : this(null, null)
        {
        }

        protected Control(Name id)
            : this(id, id)
        {
        }

        private Control(Name id, Name name)
        {
            this.Id = id;
            this.Name = name;
        }

        public bool Disabled
        {
            get;
            set;
        }

        public bool IsValid
        {
            get
            {
                bool value = true;

                if (null != this.Validator)
                {
                    value = this.Validator.Validate(this);
                }

                return value;
            }
        }

        public Name Name
        {
            get;
            set;
        }

        public bool Suppress
        {
            get;
            set;
        }

        public int? TabIndex
        {
            get;
            set;
        }

        public IValidate Validator
        {
            get;
            set;
        }

        public abstract string Value { get; set; }

        public virtual DataCollection ToDataCollection()
        {
            DataCollection result = new DataCollection();

            if (!this.Suppress && !string.IsNullOrEmpty(this.Name))
            {
                result.Add(this.Name, this.Value);
            }

            return result;
        }

        public HiddenInput ToHiddenInput()
        {
            return new HiddenInput(
                this.Id,
                this.Name,
                this.Value);
        }

        public virtual void Update(Name name, string value)
        {
            if (this.Name == name)
            {
                this.Value = value;
            }
        }

        public override void ReadXml(XmlReader reader)
        {
            base.ReadXml(reader);
            
            if (XmlNodeType.Element == reader.NodeType)
            {
                string value = reader.GetAttribute("name");
                if (!string.IsNullOrEmpty(value))
                {
                    this.Name = value;
                }

                value = reader.GetAttribute("tabindex");
                if (!string.IsNullOrEmpty(value))
                {
                    this.TabIndex = XmlConvert.ToInt32(value);
                }

                this.Disabled = "disabled".Equals(reader.GetAttribute("disabled"), StringComparison.OrdinalIgnoreCase);
            }
        }

        public override void WriteXml(XmlWriter writer)
        {
            base.WriteXml(writer);

            if (null != this.Name)
            {
                writer.WriteAttributeString("name", this.Name);
            }

            if (this.TabIndex.HasValue)
            {
                writer.WriteAttributeString("tabindex", XmlConvert.ToString(this.TabIndex.Value));
            }

            if (this.Disabled)
            {
                writer.WriteAttributeString("disabled", "disabled");
            }
        }
    }
}